import re
from time import sleep

from selenium.webdriver.common.by import By

from hslib.webdriver.data_change import get_same_value_in_lists, deal_inputdata
from qturboframe.lib.webdriver.remote.webdriver import WebDriver
from qturboframe.lib.webdriver.remote.webelement import WebElement
from qturboframe.lib.webdriver.exceptions import SeleniumError
from qturboframe.lib.report.log import logger
from qturboframe.public_ui.jresui2.form import Form

from .base_element import BaseElement

class Table(BaseElement):
    """
    table表格操作

    :Attributes:
     - _driver: 控件所在的当前webdriver对象
     - _element: 控件元素webelement对象
     - timeout: 步骤操作的超时时间

    :Raises:
        当element_para类型错误时则抛出AttributeError异常

    :Example:
     - 例1: Table(webelement)
     - 例2: Table({By.CLASS_NAME:'class_name','text':'文本信息'})
     - 例3: Table({By.CLASS_NAME:'class_name','text':'文本信息'}, father=driver)
     - 例4: Table({By.CLASS_NAME:'class_name','text':'文本信息'}, father=webelement)
    """
    def __init__(self, element_para, father=None, timeout=5):
        # element_para入参为字符串类型时，默认为查询方式为id
        if isinstance(element_para, str):
            element_para = {By.ID: element_para}
        if isinstance(element_para, WebElement):
            self._element = element_para
            self._driver = element_para._parent
            self.timeout = timeout
        elif not isinstance(element_para, dict):
            raise AttributeError('element_para参数类型不正确！')
        else:
            if father is None:
                raise AttributeError('未定位元素，father参数不能为None！')
            if isinstance(father, WebDriver):
                self._driver = father
                self.timeout = timeout
            elif isinstance(father, WebElement):
                self._driver = father._parent
                self.timeout = timeout
            else:
                raise AttributeError('father参数类型不正确！')
            key_list = [By.ID, By.NAME, By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT,
                        By.PARTIAL_LINK_TEXT, By.CSS_SELECTOR, By.XPATH]
            element_by = ''
            element_value = ''
            assist = ''
            for key, value in element_para.items():
                if key in key_list:
                    element_by = key
                    element_value = value
                else:
                    assist += '{}:{},'.format(key, value)
            assist = assist.strip(',')
            self._elements = father.find_elements_by_attribute(
                element_by, element_value, assist, self.timeout)
            #选出第一个display: block的tabel
            for element in self._elements:
                if element.is_displayed():
                    self._element = element
                    break
            else:
                raise SeleniumError("请确定输入参数，没有找到合适的table")


    def get_table_title_list(self, table_element):
        """
        Jres2.0 获取table对象的列名

        :Returns:
            返回table的列名列表

        :Raises:
            SeleniumError: 当前元素不是table

        :Example:
         - 例: select.get_table_title_list(table)
        """
        if not table_element:
            table_element = self._element

        if table_element.tag_name == 'table':
            title_list = list()
            #table头的xpath，不获取没有显示出来的列
            header_xpath = ".//tr[1]/td[not(contains(@style,'display: none')) and not(contains(@style,'display:none'))]"
            header_list = table_element.find_elements_by_attribute('xpath', header_xpath, timeout=self.timeout)

            for header in header_list:
                title_list.append(BaseElement(header).get_text())
                
            return title_list
        else:
            logger.debug('元素对象不为table对象，对象类型为：' + self._element.tag_name)
            raise SeleniumError('元素对象不为table对象，对象类型为：' + self._element.tag_name)

    def get_table_text_list(self, table_element=None, columns=0, column=0):
        """
        Jres2.0 获取table对象的内容

        :Args:
         - columns: table的总列数
         - column: table的第几列

        :Returns:
            返回table的列内容，默认返回table的所有内容

        :Raises:
            SeleniumError: 当前元素不是table

        :Example:
         - 例: select.get_table_text_list(table)
        """
        if not table_element:
            table_element = self._element
        
        if table_element.tag_name == 'table':
            bodylist = list()
            tbody = table_element.find_element_by_attribute('tag name', 'tbody', timeout=3)
            trlist = tbody.find_elements_by_attribute('tag name', 'tr', timeout=3)
            for tr in trlist:
                try:
                    try:
                        tlist = tr.find_elements_by_attribute('tag name', 'td', timeout=1)
                    except:
                        tlist = tr.find_elements_by_attribute('tag name', 'th', timeout=1)
                except:
                    pass
                else:
                    for t in tlist:
                        bodylist.append(t)
            textlist = list()
            for i in range(0, len(bodylist)):
                if columns:
                    if (i + 1) % columns == column % columns:
                        text = bodylist[i].text.strip()
                        textlist.append(text)
                else:
                    text = bodylist[i].text.strip()
                    textlist.append(text)
            return textlist
        else:
            logger.debug('元素对象不为table对象，对象类型为：' + self._element.tag_name)
            raise SeleniumError('元素对象不为table对象，对象类型为：' + self._element.tag_name)

    def get_table_cell_list(self, columns=0, column=0):
        """
        Jres2.0 获取table对象的单元格集合

        :Args:
         - columns: table的总列数
         - column: table的第几列

        :Returns:
            返回table的列单元格元素集合，默认返回table的所有单元格元素集合

        :Raises:
            SeleniumError: 当前元素不是table

        :Example:
         - 例: select.get_table_cell_list(columns=0, column=0)
        """
        if self._element.tag_name == 'table':
            #bodystr=self.getelementbyattribute(r'tag name:tbody').gettext()
            #bodylist=re.findall(r'[^\n]+',bodystr)
            bodylist = list()
            tbody=self._element.find_element_by_attribute('tag name', 'tbody', timeout=3)
            trlist=tbody.find_elements_by_attribute('tag name', 'tr', timeout=3)
            for tr in trlist:
                try:
                    try:
                        tlist = tr.find_elements_by_attribute('tag name', 'td', timeout=1)
                    except:
                        tlist = tr.find_elements_by_attribute('tag name', 'th', timeout=1)
                except:
                    pass
                else:
                    for t in tlist:
                        bodylist.append(t)
            celllist = list()
            for i in range(0, len(bodylist)):
                if columns:
                    if (i + 1) % columns == column % columns:
                        celllist.append(bodylist[i])
                else:
                    celllist.append(bodylist[i])
            return celllist
        else:
            logger.debug('元素对象不为table对象，对象类型为：' + self._element.tag_name)
            raise SeleniumError('元素对象不为table对象，对象类型为：' + self._element.tag_name)
        
    def get_datagrid_table_row(self, tableinfo, idname:dict=dict(), father=None):
        '''
        Jres2.0 根据列名和列名信息查找jres2.0的表格中所在的行数，第一个table为列名，第二个table为内容

        :Args:
         - tableinfo: 输入数据，列名和列名信息
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            返回行数

        :Raises:
            SeleniumError: 表格行数查找失败

        :Example:
         - 例: select.get_datagrid_table_row(table,{"xpath",".//*[@class='class']"})
        '''
        try:
            if father is None:
                father = self._driver

            if isinstance(idname, dict) and len(idname) != 0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    key_list = [By.ID, By.NAME, By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT,
                                By.PARTIAL_LINK_TEXT, By.CSS_SELECTOR, By.XPATH]
                    if key in key_list:
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
                                                          timeout=self.timeout)
            else:
                topdiv = father.find_element_by_attribute('xpath',
                                                          '//div[@class="xdatagrid g-datagrid-wrap"]',
                                                          timeout=self.timeout)
            # 翻到首页
            page_div = topdiv.find_element_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                        timeout=self.timeout)

            locator = 'a.refresh_btn,span.uf-datagrid-refresh'
            refresh_button = page_div.find_element_by_attribute('css selector', locator,timeout=self.timeout)
            # refresh_button.secure_click()
            BaseElement(refresh_button).click()
            sleep(0.5)

            first_btn_locator = 'a.first_page_btn,a.pre_page_btn'
            first_button = page_div.find_element_by_attribute('css selector', first_btn_locator,timeout=self.timeout)
            if 'disabled' not in first_button.get_attribute('class'):
                first_button.secure_click()
                sleep(0.5)
            # 定位表格
            headtable = topdiv.find_element_by_attribute('xpath',
                                                         './div[@class=\'hc-datagrid-header\']/table[1]',
                                                         timeout=self.timeout)
            body_div = topdiv.find_elements_by_attribute('css selector', 'div.hc-datagrid-body',
                                                         timeout=self.timeout)[0]
            bodytable = body_div.find_element_by_attribute('tag name', 'table', timeout=self.timeout)
            return self.__get_table_row(topdiv, headtable, bodytable, tableinfo)
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))

    def get_datagrid_table_cell(self, titlename, row, idname:dict=dict(), father=None):
        '''
        Jres2.0 根据列名和行数查找所在jres2.0的表格的单元格信息，第一个table为列名，第二个table为内容

        :Args:
         - titlename: 列名
         - row: 单元格所在的行数
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            返回查找的单元格

        :Raises:
            SeleniumError: 查找单元格失败

        :Example:
         - 例: select.get_datagrid_table_cell(titlename,{"xpath",".//*[@class='class']"})
        '''
        try:
            re_fixedtable = r'hc-datagrid-fixed-table'
            table_cell = None
            if father is None:
                father = self._driver

            if isinstance(idname, dict) and len(idname) != 0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    key_list = [By.ID, By.NAME, By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT,
                                By.PARTIAL_LINK_TEXT, By.CSS_SELECTOR, By.XPATH]
                    if key in key_list:
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
                                                          timeout=self.timeout)
            else:
                topdiv = father.find_element_by_attribute('xpath',
                                                          '//div[@class="xdatagrid g-datagrid-wrap"]',
                                                          timeout=self.timeout)
            # 翻到首页
            page_div = topdiv.find_element_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                        timeout=self.timeout)
            locator = 'a.refresh_btn,span.uf-datagrid-refresh'
            refresh_button = page_div.find_element_by_attribute('css selector', locator, timeout=self.timeout)
            # refresh_button.secure_click()
            BaseElement(refresh_button).click()
            sleep(0.5)

            first_btn_locator = 'a.first_page_btn,a.pre_page_btn'
            first_button = page_div.find_element_by_attribute('css selector', first_btn_locator,timeout=self.timeout)
            if 'disabled' not in first_button.get_attribute('class'):
                first_button.secure_click()
                sleep(0.5)
            # 定位表格
            headtable = topdiv.find_element_by_attribute('xpath',
                                                         './div[@class=\"hc-datagrid-header\"]/table',
                                                         timeout=self.timeout)
            bodytable = topdiv.find_element_by_attribute('xpath',
                                                         './div[@class=\"hc-datagrid-body\"]/table',
                                                         timeout=self.timeout)
            # 进行表格查找
            if (re.search(re_fixedtable, headtable.get_attribute('class')) and re.search(re_fixedtable, bodytable.get_attribute('class'))):
                table_cell = self.__get_table_cell(topdiv, headtable, bodytable, titlename, row)
            else:
                raise SeleniumError('表格格式错误！')
            return table_cell
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))

    def get_freezen_table_row(self, tableinfo, idname:dict=dict(), father=None):
        '''
        Jres2.0 根据列名和列名信息查找jres2.0的表格中所在的行数，第一个table为列名，第二个table为内容

        :Args:
         - tableinfo: 输入数据，列名和列名信息
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            返回表格查找的行数

        :Raises:
            SeleniumError: 查找表格行数失败

        :Example:
         - 例: select.get_freezen_table_row(tableinfo,{"xpath",".//*[@class='class']"})
        '''
        try:
            if father is None:
                father = self._driver
                
            if isinstance(idname, dict) and len(idname)!=0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    if key in key_list:
                        key_list = [By.ID, By.NAME, By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT,
                                    By.PARTIAL_LINK_TEXT, By.CSS_SELECTOR, By.XPATH]
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist, timeout=self.timeout)
            else:
                topdiv = father.find_element_by_attribute('xpath',
                                                          '//div[@class="xdatagrid g-datagrid-wrap"]',
                                                          timeout=self.timeout)
            # 翻到首页
            page_div = topdiv.find_element_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                        timeout=self.timeout)
            refresh_button = page_div.find_element_by_attribute('css selector', 'a.refresh_btn,span.uf-datagrid-refresh',
                                                                timeout=self.timeout)
            refresh_button.secure_click()
            sleep(0.5)
            first_button = page_div.find_element_by_attribute('css selector', 'a.first_page_btn,a.pre_page_btn',
                                                              timeout=self.timeout)
            if 'disabled' not in first_button.get_attribute('class'):
                first_button.secure_click()
                sleep(0.5)
            # 定位表格
            headtable = topdiv.find_element_by_attribute('xpath',
                                                         './div[@class=\'hc-datagrid-header\']/table[1]',
                                                         timeout=self.timeout)
            body_div = topdiv.find_elements_by_attribute('css selector', 'div.hc-datagrid-body',
                                                         timeout=self.timeout)[1]
            bodytable = body_div.find_element_by_attribute('tag name', 'table', timeout=self.timeout)
            return self.__get_table_row(topdiv, headtable, bodytable, tableinfo)
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))

    def get_freezen_table_cell(self, titlename, row, idname:dict=dict(), father=None):
        '''
        Jres2.0 根据列名和行数查找jres2.0的表格中单元格，第一个table为列名，第二个table为内容

        :Args:
         - titlename: 列名
         - row: 单元格所在的行数
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            返回查找的单元格

        :Raises:
            SeleniumError: 查找单元格失败

        :Example:
         - 例: select.get_freezen_table_cell(titlename,{"xpath",".//*[@class='class']"})
        '''
        try:
            re_fixedtable = r'hc-datagrid-fixed-table'
            table_cell = None
            if father is None:
                father = self._driver
            if isinstance(idname, dict) and len(idname)!=0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    if key in key_list:
                        key_list = [By.ID, By.NAME, By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT,
                                    By.PARTIAL_LINK_TEXT, By.CSS_SELECTOR, By.XPATH]
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist, timeout=self.timeout)
            else:
                topdiv = father.find_element_by_attribute('xpath',
                                                          '//div[@class="xdatagrid g-datagrid-wrap"]',
                                                          timeout=self.timeout)
            # 翻到首页
            page_div = topdiv.find_element_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                        timeout=self.timeout)
            refresh_locator = 'a.refresh_btn,span.uf-datagrid-refresh'
            refresh_button = page_div.find_element_by_attribute('css selector', refresh_locator,
                                                                timeout=self.timeout)
            BaseElement(refresh_button).click()
            sleep(0.5)
            first_btn_locator = 'a.first_page_btn,a.pre_page_btn'
            first_button = page_div.find_element_by_attribute('css selector', first_btn_locator,
                                                              timeout=self.timeout)
            if 'disabled' not in first_button.get_attribute('class'):
                BaseElement(first_button).click()
                sleep(0.5)
            # 定位表格
            headtable = topdiv.find_element_by_attribute('xpath',
                                                         './div[@class=\'hc-datagrid-header\']/table[2]',
                                                         timeout=self.timeout)
            body_div = topdiv.find_elements_by_attribute('css selector', 'div.hc-datagrid-body',
                                                         timeout=self.timeout)[1]
            bodytable = body_div.find_element_by_attribute('tag name', 'table', timeout=self.timeout)
            # 进行表格查找
            if (re.search(re_fixedtable, headtable.get_attribute('class')) and
                    re.search(re_fixedtable, bodytable.get_attribute('class'))):
                table_cell = self.__get_table_cell(topdiv, headtable, bodytable, titlename, row)
            else:
                raise SeleniumError('表格格式错误！')
            return table_cell
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))

    def set_freezen_table_rows_in_page(self, rows, idname:dict=dict(), father=None):
        '''
        设置jres2.0的表格分页栏的每页显示行数，适用网站类型分页表格

        :Args:
         - rows: 要设置的单页显示行数
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Example:
         - 例: select.get_freezen_table_cell(rows,{"xpath",".//*[@class='class']"})
        '''
        try:
            if father is None:
                father = self._driver
            if isinstance(idname, dict) and len(idname) != 0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    if key in key_list:
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
                                                          timeout=self.timeout)
            else:
                topdiv = father.find_element_by_attribute('xpath', '//div[@class="xdatagrid g-datagrid-wrap"]',
                                                          timeout=self.timeout)

            page_div = topdiv.find_element_by_attribute('xpath', '//div[@class="u-web-page"]',
                                                                      timeout=self.timeout)
            rows_input = page_div.find_element_by_attribute('name', 'pageSize',
                                                                          timeout=self.timeout)
            rows_input.clear()
            rows_input.send_keys(rows)
        except Exception as msg:
            logger.warn(str(msg))

    def __get_table_row(self, tablediv, headtable, bodytable, tableinfo):
        '''
        根据列名和文本查找表格中所在的行数

        :Args:
         - tablediv: 表格div元素
         - headtable: 列名表格
         - bodytable: 内容表格
         - tableinfo: 列名和列名信息

        :Returns:
            返回行数

        :Raises:
            SeleniumError: 表格格式错误或者未找到数据行
        '''
        re_fixedtable = r'hc-datagrid-fixed-table'
        keylist = list(tableinfo.keys())
        logger.debug("表格查找列名索引：" + str(keylist))
        # 进行表格查找
        if (re.search(re_fixedtable, headtable.get_attribute('class')) and
                re.search(re_fixedtable, bodytable.get_attribute('class'))):
            # 获取当前表格显示的列名和数据
            # titlelist = headtable.get_table_text()
            titlelist = self.get_table_text_list(headtable)
            logger.debug('表格当前显示列名：' + str(titlelist))
            rowlist_list = list()
            rows = 0
            for key in keylist:
                titleindex = titlelist.index(key)
                logger.debug("第" + str(titleindex + 1) + '列，名称：' + key)
                # textlist = bodytable.get_table_text(len(titlelist), int(titleindex + 1))
                textlist = self.get_table_text_list(bodytable,len(titlelist), int(titleindex + 1))
                rows = len(textlist)
                logger.debug("当前页显示行数：" + str(rows))
                templist = list()
                for j in range(0, rows):
                    if textlist[j] == tableinfo.get(key):
                        # logger.debug('第' + str(j + 1) + '行，内容：' +
                        #                          textlist[titleindex + (j * len(titlelist))])
                        row = j + 1
                        templist.append(row)
                rowlist_list.append(templist)
            rowlist = rowlist_list[0]
            for i in range(1, len(rowlist_list)):
                rowlist = get_same_value_in_lists(rowlist, rowlist_list[i])
            # 未找到数据行则进行表格翻页
            if len(rowlist) > 0:
                return rowlist[0]
            else:
                # 进行翻页操作
                page_div = tablediv.find_element_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                              timeout=self.timeout)
                # refresh_button = page_div.find_element_by_attribute('css selector', 'a.refresh_btn',
                #                                                     timeout=self.timeout)
                # refresh_button.secure_click()
                # sleep(0.5)
                next_button = page_div.find_element_by_attribute('css selector', 'a.next_page_btn',timeout=self.timeout)

                if 'disabled' not in next_button.get_attribute('class'):
                    logger.debug('翻下一页查找。')
                    BaseElement(next_button).click()
                    sleep(0.5)
                    return self.__get_table_row(tablediv, headtable, bodytable, tableinfo) + rows
                else:
                    raise SeleniumError('未找到目标数据行！')
        else:
            raise SeleniumError('表格格式错误！')

    def __get_table_cell(self, tablediv, headtable, bodytable, titlename, row):
        '''
        根据列名和行数查找表格中单元格

        :Args:
         - tablediv: 表格div元素
         - headtable: 列名表格
         - bodytable: 内容表格
         - titlename: 列名
         - row: 单元格所在的行数

        :Returns:
            返回表格单元格

        :Raises:
            SeleniumError: 表格的行号超出范围
        '''
        table_cell = None
        # 获取当前表格显示的列名和数据
        # titlelist = headtable.get_table_text()
        titlelist = self.get_table_text_list(headtable)
        logger.debug('表格当前显示列名：' + str(titlelist))
        celllist = bodytable.find_elements_by_attribute('xpath', './tbody/*/td', timeout=self.timeout)
        # 计算当前表格显示的行数
        rows = len(celllist) / len(titlelist)
        logger.debug('当前显示行数：{}/{}={}'.format(len(celllist), len(titlelist), rows))
        if row <= 0:
            raise SeleniumError('表格行号出错！')
        elif row > rows:
            # 进行翻页操作
            page_div = tablediv.find_element_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                          timeout=self.timeout)
            # refresh_button = page_div.find_element_by_attribute('css selector', 'a.refresh_btn',
            #                                                     timeout=self.timeout)
            # refresh_button.secure_click()
            # sleep(0.5)
            next_button = page_div.find_element_by_attribute('css selector', 'a.next_page_btn',
                                                             timeout=self.timeout)
            if 'disabled' not in next_button.get_attribute('class'):
                logger.debug('翻下一页查找。')
                BaseElement(next_button).click()
                sleep(0.5)
                table_cell = self.__get_table_cell(tablediv, titlelist, celllist, titlename, (row - rows))
            else:
                raise SeleniumError('行数已超出表格总行数！')
        else:
            titleindex = titlelist.index(titlename)
            logger.debug(str(titleindex) + '列，名称' + titlename)
            table_cell = celllist[int(titleindex + (len(titlelist) * (row - 1)))]
        return table_cell

    def get_table_list_row(self, tableinfo, idname:dict=dict(), father=None):
        '''
        根据列名和列名信息查找jres2.0的表格中所在的行数，表格中带thead，多选表格列表

        :Args:
         - tableinfo:输入数据，列名和列名信息组
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            返回行号

        :Raises:
            SeleniumError: 未找到查找的行号

        :Example:
         - 例: select.get_table_list_row(table, {"xpath",".//*[@class='class']"})
        '''
        try:
            if father is None:
                father = self._driver

            if isinstance(idname, dict) and len(idname) != 0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    if key in key_list:
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
                                                          timeout=self.timeout)
            else:
                topdiv = father.find_element_by_attribute('xpath',
                                                          '//div[@class="xdatagrid g-datagrid-wrap"]',
                                                          timeout=self.timeout)
            # 翻到首页
            page_div = topdiv.find_element_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                        timeout=self.timeout)

            locator = 'a.refresh_btn,span.uf-datagrid-refresh'
            refresh_button = page_div.find_element_by_attribute('css selector', locator,
                                                                timeout=self.timeout)
            BaseElement(refresh_button).click()
            sleep(0.5)
            first_btn_locator = 'a.first_page_btn,a.pre_page_btn'
            first_button = page_div.find_element_by_attribute('css selector', first_btn_locator,
                                                              timeout=self.timeout)
            if 'disabled' not in first_button.get_attribute('class'):
                BaseElement(first_button).click()
                sleep(0.5)
            return self.__get_table_list_page_row(topdiv, tableinfo)
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))

    def get_table_list_cell(self, titlename, row, idname:dict=dict(), father=None):
        '''
        根据列名和行数查找所在jres2.0的表格的单元格信息，表格中带thead，多选表格列表

        :Args:
         - titlename: 列名
         - row: 行数
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            返回查找的单元格

        :Raises:
            SeleniumError: 未找到查找的单元格

        :Example:
         - 例: select.get_table_list_cell(titlename, {"xpath",".//*[@class='class']"})
        '''
        try:
            re_datagrid = r'datagrid-table'
            re_fixedtable = r'hc-datagrid-fixed-table'
            table_cell = None
            if father is None:
                father = self._driver

            if isinstance(idname, dict) and len(idname) != 0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    if key in key_list:
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
                                                          timeout=self.timeout)
            else:
                topdiv = father.find_element_by_attribute('xpath',
                                                          '//div[@class="xdatagrid g-datagrid-wrap"]',
                                                          timeout=self.timeout)
            # 翻到首页
            page_div = topdiv.find_element_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                        timeout=self.timeout)
            locator = 'a.refresh_btn,span.uf-datagrid-refresh'
            refresh_button = page_div.find_element_by_attribute('css selector', locator,
                                                                timeout=self.timeout)
            # refresh_button.secure_click()
            BaseElement(refresh_button).click()
            sleep(0.5)

            first_btn_locator = 'a.first_page_btn,a.pre_page_btn'
            first_button = page_div.find_element_by_attribute('css selector', first_btn_locator,
                                                              timeout=self.timeout)
            if 'disabled' not in first_button.get_attribute('class'):
                # first_button.secure_click()
                BaseElement(first_button).click()
                sleep(0.5)
            table = topdiv.find_element_by_attribute('xpath', './div[@class=\'hc-datagrid-body\']/table',
                                                     timeout=self.timeout)
            if (re.search(re_datagrid, table.get_attribute('class')) and
                    re.search(re_fixedtable, table.get_attribute('class'))):
                table_cell = self.__get_table_list_page_cell(topdiv, table, titlename, row)
            else:
                logger.error('表格格式错误！')
                raise SeleniumError('表格格式错误！')
            return table_cell
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))

    def __get_table_title_in_td(self, table):
        if table.tag_name == 'table':
            titlelist = list()
            thead = table.find_element_by_attribute('tag name', 'thead', timeout=self.timeout)
            trlist = thead.find_elements_by_attribute('tag name', 'tr', timeout=self.timeout)
            for tr in trlist:
                tlist = tr.find_elements_by_attribute('tag name', 'td', timeout=self.timeout)
                for t in tlist:
                    text = t.text
                    titlelist.append(text)
            return titlelist
        else:
            raise SeleniumError('元素对象不为table对象，对象类型为：'+table.tag_name)

    def __get_table_list_page_row(self, tablediv, tableinfo):
        '''
        根据列名和文本查找表格中所在的行数

        :Args:
         - tablediv: 表格div元素
         - tableinfo: 输入数据，列名和列名信息组

        :Returns:
            返回行号

        :Raises:
            SeleniumError: 表格格式错误或者未找到数据行
        '''
        re_datagrid = r'datagrid-table'
        re_fixedtable = r'hc-datagrid-fixed-table'
        keylist = list(tableinfo.keys())
        logger.debug("表格查找列名索引：" + str(keylist))
        # 进行表格查找
        table = tablediv.find_element_by_attribute('xpath', './div[@class=\'hc-datagrid-body\']/table',
                                                   timeout=self.timeout)
        if (re.search(re_datagrid, table.get_attribute('class')) and
                re.search(re_fixedtable, table.get_attribute('class'))):
            # 获取当前表格显示的列名和数据
            titlelist = self.__get_table_title_in_td(table)
            logger.debug('表格当前显示列名：' + str(titlelist))
            rowlist_list = list()
            rows = 0
            for key in keylist:
                # 表格当前页查找
                titleindex = titlelist.index(key)
                logger.debug("第" + str(titleindex + 1) + '列，名称：' + key)
                # textlist = table.get_table_text(len(titlelist), int(titleindex + 1))
                textlist = self.get_table_text_list(table,len(titlelist), int(titleindex + 1))
                rows = len(textlist)
                logger.debug("当前页显示行数：" + str(rows))
                templist = list()
                for j in range(0, len(textlist)):
                    if textlist[j] == tableinfo[key]:
                        logger.debug('第' + str(j + 1) + '行，内容：' + textlist[j])
                        row = j + 1
                        templist.append(row)
                rowlist_list.append(templist)
            rowlist = rowlist_list[0]
            for i in range(1, len(rowlist_list)):
                rowlist = get_same_value_in_lists(rowlist, rowlist_list[i])
            # 未找到数据行则进行表格翻页
            if len(rowlist) > 0:
                return rowlist[0]
            else:
                # 进行翻页操作
                page_div = tablediv.find_element_by_attribute('xpath', './div[@class=\'u-datagrid-page\']',
                                                              timeout=self.timeout)
                refresh_button = page_div.find_element_by_attribute('css selector', 'a.refresh_btn',
                                                                    timeout=self.timeout)
                refresh_button.secure_click()
                sleep(0.5)
                next_button = page_div.find_element_by_attribute('css selector', 'a.next_page_btn',
                                                                 timeout=self.timeout)
                if 'disabled' not in next_button.get_attribute('class'):
                    logger.debug('翻下一页查找。')
                    next_button.secure_click()
                    sleep(0.5)
                    return self.__get_table_list_page_row(tablediv, tableinfo) + rows
                else:
                    raise SeleniumError('未找到目标数据行！')
        else:
            raise SeleniumError('表格格式错误！')

    def __get_table_list_page_cell(self, tablediv, table, titlename, row):
        '''
        根据列名和行数查找表格中单元格

        :Args:
         - tablediv: 表格div元素
         - table: 表格
         - titlename: 列名
         - row: 单元格所在的行数

        :Returns:
            返回表格单元格

        :Raises:
            SeleniumError: 行号超出表格范围
        '''
        table_cell = None
        # 获取表格当前页列名和数据
        titlelist = self.__get_table_title_in_td(table)
        logger.debug('表格当前显示列名：' + str(titlelist))
        celllist = table.find_elements_by_attribute('xpath:./tbody/*/td', timeout=self.timeout)
        # 计算表格当前页显示行数
        rows = len(celllist) / len(titlelist)
        logger.debug('当前显示行数：{}/{}={}'.format(len(celllist), len(titlelist), rows))
        if row <= 0:
            raise SeleniumError('表格行号出错！')
        elif row > rows:
            # 进行翻页操作
            page_div = tablediv.find_element_by_attribute('xpath', './div[@class=\'u-datagrid-page\']',
                                                          timeout=self.timeout)
            refresh_button = page_div.find_element_by_attribute('css selector', 'a.refresh_btn',
                                                                timeout=self.timeout)
            refresh_button.secure_click()
            sleep(0.5)
            next_button = page_div.find_element_by_attribute('css selector', 'a.next_page_btn',
                                                             timeout=self.timeout)
            if 'disabled' not in next_button.get_attribute('class'):
                logger.debug('翻下一页查找。')
                next_button.secure_click()
                sleep(0.5)
                table_cell = self.__get_table_list_page_cell(tablediv, table, titlename, (row - rows))
            else:
                raise SeleniumError('行数已超出表格总行数！')
        else:
            titleindex = titlelist.index(titlename)
            logger.debug(str(titleindex) + '列，名称' + titlename)
            table_cell = celllist[int(titleindex + (len(titlelist) * (row - 1)))]
        return table_cell

    def get_table_list_cell_merge(self, tableinfo, titlename, idname:dict=dict(), father=None):
        '''
        根据列名和列名信息查找jres2.0的表格中所在的单元格，表格中带thead，多选表格列表

        :Args:
         - tableinfo:查找行号所需的列名和列名信息组
         - titlename:待查找单元格所在的列名
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            返回查找的单元格

        :Raises:
            SeleniumError: 未找到查找的单元格

        :Example:
         - 例: select.get_table_list_cell_merge(table, {"xpath",".//*[@class='class']"})
        '''
        try:
            if father is None:
                father = self._driver
            if isinstance(idname, dict) and len(idname) != 0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    if key in key_list:
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
                                                          timeout=self.timeout)
            else:
                topdiv = father.find_element_by_attribute('xpath',
                                                          '//div[@class="xdatagrid g-datagrid-wrap"]',
                                                          timeout=self.timeout)
            # 翻到首页
            page_div = topdiv.find_element_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                        timeout=self.timeout)

            locator = 'a.refresh_btn,span.uf-datagrid-refresh'
            refresh_button = page_div.find_element_by_attribute('css selector', locator,
                                                                timeout=self.timeout)
            # refresh_button.secure_click()
            BaseElement(refresh_button).click()
            sleep(0.5)

            first_btn_locator = 'a.first_page_btn,a.pre_page_btn'
            first_button = page_div.find_element_by_attribute('css selector', first_btn_locator,
                                                              timeout=self.timeout)
            if 'disabled' not in first_button.get_attribute('class'):
                # first_button.secure_click()
                BaseElement(first_button).click()
                sleep(0.5)
            return self.__get_table_list_page_cell_merge(topdiv, tableinfo, titlename)
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))

    def __get_table_list_page_cell_merge(self, tablediv, tableinfo, titlename):
        re_datagrid = r'datagrid-table'
        re_fixedtable = r'hc-datagrid-fixed-table'
        keylist = list(tableinfo.keys())
        logger.debug('表格查找列名索引：' + str(keylist))
        # 进行表格查找
        table = tablediv.find_element_by_attribute('xpath', './div[@class=\'hc-datagrid-body\']/table',
                                                   timeout=self.timeout)
        if (re.search(re_datagrid, table.get_attribute('class')) and
                re.search(re_fixedtable, table.get_attribute('class'))):
            # 获取当前表格显示的列名和数据
            titlelist = self.__get_table_title_in_td(table)
            logger.debug('表格当前显示列名：' + str(titlelist))
            rowlist_list = list()
            rows = 0
            for key in keylist:
                # 表格当前页查找
                titleindex = titlelist.index(key)
                logger.debug('第' + str(titleindex + 1) + '列，名称：' + key)
                # textlist = table.get_table_text(len(titlelist), int(titleindex + 1))
                textlist = self.get_table_text_list(table,len(titlelist), int(titleindex + 1))
                rows = len(textlist)
                logger.debug('当前页显示行数：' + str(rows))
                templist = list()
                for j in range(0, len(textlist)):
                    if textlist[j] == tableinfo[key]:
                        logger.debug('第' + str(j + 1) + '行，内容：' + textlist[j])
                        row = j + 1
                        templist.append(row)
                rowlist_list.append(templist)
            rowlist = rowlist_list[0]
            for i in range(1, len(rowlist_list)):
                rowlist = get_same_value_in_lists(rowlist, rowlist_list[i])
            # 未找到数据行则进行表格翻页
            if len(rowlist) > 0:
                # 根据row和当前表格页查找Cell
                celllist = table.find_elements_by_attribute('xpath', './tbody/*/td', timeout=self.timeout)
                titleindex = titlelist.index(titlename)
                logger.debug(str(titleindex) + '列，名称' + titlename)
                return celllist[int(titleindex + (len(titlelist) * (rowlist[0] - 1)))]
            else:
                # 进行翻页操作
                page_div = tablediv.find_element_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                              timeout=self.timeout)
                refresh_button = page_div.find_element_by_attribute('css selector', 'a.refresh_btn',
                                                                    timeout=self.timeout)
                refresh_button.secure_click()
                sleep(0.5)
                next_button = page_div.find_element_by_attribute('css selector', 'a.next_page_btn',
                                                                 timeout=self.timeout)
                if 'disabled' not in next_button.get_attribute('class'):
                    logger.debug('翻下一页查找。')
                    next_button.secure_click()
                    sleep(0.5)
                    return self.__get_table_list_page_cell_merge(tablediv, tableinfo, titlename)
                else:
                    raise SeleniumError('未找到目标数据行！')
        else:
            raise SeleniumError('表格格式错误！')

    def get_form_table_row(self, tableinfo, idname:dict=dict(), father=None):
        '''
        根据列名和列名信息查找jres2.0的表格中所在的行数，表格中带thead，静态表格

        :Args:
         - tableinfo: 输入数据，列名和列名信息
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            返回表格的行数

        :Raises:
            SeleniumError: 未查找到数据行数

        :Example:
         - 例: select.get_form_table_row(table, {"xpath",".//*[@class='class']"})
        '''
        try:
            row = 0
            keylist = list(tableinfo.keys())
            logger.debug('表格查找列名索引：' + str(keylist))
            if father is None:
                father = self._driver
            if isinstance(idname, dict) and len(idname) != 0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    if key in key_list:
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
                                                          timeout=self.timeout)
            else:
                topdiv = father.find_element_by_attribute('xpath',
                                                          '//div[@class="h_formtable g-datagrid-wrap"]',
                                                          timeout=self.timeout)
            # 翻至表格首页
            page_div = topdiv.find_element_by_attribute('xpath',
                                                        './following-sibling::div[@class=\"u-datagrid-page\"]',
                                                        timeout=self.timeout)
            first_page = page_div.find_element_by_attribute('css selector', 'li>a.first_page_btn',
                                                            timeout=self.timeout)
            if 'disable' not in first_page.get_attribute('class'):
                # first_page.secure_click()
                BaseElement(first_page).click()
                sleep(0.5)
            return self.__get_table_page_row(topdiv, tableinfo)
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))

    def get_form_table_cell(self, tableinfo, row, idname:dict=dict(), father=None):
        '''
        根据列名和行数查找所在jres2.0的表格的单元格信息，表格中带thead

        :Args:
         - tableinfo: 列名
         - row: 行数
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            返回表格单元格

        :Raises:
            SeleniumError: 未找到表格的单元格

        :Example:
         - 例: select.get_form_table_cell(table, {"xpath",".//*[@class='class']"})
        '''
        try:
            re_datagrid = r'datagrid-table'
            re_fixedtable = r'hc-datagrid-fixed-table'
            table_cell = None

            if father is None:
                father = self._driver
            if isinstance(idname, dict) and len(idname) != 0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    if key in key_list:
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
                                                          timeout=self.timeout)
            else:
                topdiv = father.find_element_by_attribute('xpath',
                                                          '//div[@class="h_formtable g-datagrid-wrap"]',
                                                          timeout=self.timeout)
            # 翻至表格首页
            page_div = topdiv.find_element_by_attribute('xpath',
                                                        './following-sibling::div[@class=\"u-datagrid-page\"]',
                                                        timeout=self.timeout)
            first_page = page_div.find_element_by_attribute('css selector', 'li>a.first_page_btn',
                                                            timeout=self.timeout)
            if 'disable' not in first_page.get_attribute('class'):
                # first_page.secure_click()
                BaseElement(first_page).click()
                sleep(0.5)
            table = topdiv.find_element_by_attribute('xpath', './div[@class=\"hc-datagrid-body\"]/table',
                                                 timeout=self.timeout)
            if (re.search(re_datagrid, table.get_attribute('class')) and
                    re.search(re_fixedtable, table.get_attribute('class'))):
                table_cell = self.__get_table_page_cell(topdiv, table, tableinfo, row)
            else:
                raise SeleniumError('表格格式错误！')
            return table_cell
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))

    def __get_table_page_row(self, tablediv, tableinfo):
        '''
        根据列名和文本查找表格中所在的行数

        :Args:
         - tablediv: 表格div元素
         - tableinfo: 输入数据，列名和列名信息组

        :Returns:
            返回查找到的行号

        :Raises:
            SeleniumError: 未找到表格中的数据行
        '''
        re_datagrid = r'datagrid-table'
        re_fixedtable = r'hc-datagrid-fixed-table'
        keylist = list(tableinfo.keys())
        logger.debug('表格查找列名索引：' + str(keylist))
        # 进行表格查找
        table = tablediv.find_element_by_attribute('xpath', './div[@class=\"hc-datagrid-body\"]/table',
                                                   timeout=self.timeout)

        if (re.search(re_datagrid, table.get_attribute('class')) and
                re.search(re_fixedtable, table.get_attribute('class'))):
            # 获取当前表格显示的列名和数据
            # titlelist = table.get_table_title()
            titlelist = self.get_table_title_list(titlelist)
            logger.debug('表格当前显示列名：' + str(titlelist))
            rowlist_list = list()
            rows = 0
            for key in keylist:
                # 表格当前页查找
                titleindex = titlelist.index(key)
                logger.debug('第' + str(titleindex + 1) + '列，名称：' + key)
                # textlist = table.get_table_text(len(titlelist), int(titleindex + 1))
                textlist = self.get_table_text_list(table,len(titlelist), int(titleindex + 1))
                rows = len(textlist)
                logger.debug('当前页显示行数：' + str(rows))
                templist = list()
                for j in range(0, rows):
                    if textlist[j] == tableinfo[key]:
                        logger.debug('第' + str(j + 1) + '行，内容：' + textlist[j])
                        row = j + 1
                        templist.append(row)
                rowlist_list.append(templist)
            rowlist = rowlist_list[0]
            for i in range(1, len(rowlist_list)):
                rowlist = get_same_value_in_lists(rowlist, rowlist_list[i])
            # 未找到数据行则进行表格翻页
            if len(rowlist) > 0:
                return rowlist[0]
            else:
                # 进行翻页操作
                page_div = tablediv.find_element_by_attribute(
                    'xpath', './parent::div/descendant::div[@class=\"u-datagrid-page\"]',
                    timeout=self.timeout)
                refresh_button = page_div.find_element_by_attribute('css selector', 'a.refresh_btn',
                                                                    timeout=self.timeout)
                refresh_button.secure_click()
                sleep(0.5)
                next_button = page_div.find_element_by_attribute('css selector', 'a.next_page_btn',
                                                                 timeout=self.timeout)
                if 'disabled' not in next_button.get_attribute('class'):
                    logger.debug('翻下一页查找。')
                    next_button.secure_click()
                    sleep(0.5)
                    return self.__get_table_page_row(tablediv, tableinfo) + rows
                else:
                    raise SeleniumError('未找到目标数据行！')
        else:
            raise SeleniumError('表格格式错误！')

    def __get_table_page_cell(self, tablediv, table, titlename, row):
        '''
        根据列名和行数查找表格中单元格

        :Args:
         - tablediv: 表格div元素
         - table: 表格
         - titlename: 列名
         - row: 单元格所在的行数

        :Returns:
            返回表格单元格

        :Raises:
            SeleniumError: 行号超过了表格的范围
        '''
        table_cell = None
        # 获取表格当前页列名和数据
        # titlelist = table.get_table_title()
        titlelist = self.get_table_title_list(table)
        logger.debug('表格当前显示列名：' + str(titlelist))
        celllist = table.find_elements_by_attribute('xpath', './tbody/*/td', timeout=self.timeout)
        # 计算表格当前页显示行数
        rows = len(celllist) / len(titlelist)
        logger.debug('当前显示行数：{}/{}={}'.format(len(celllist), len(titlelist), rows))
        if row <= 0:
            logger.error('表格行号出错！')
            return None
        elif row > rows:
            # 进行翻页操作
            page_div = tablediv.find_elements_by_attribute('xpath', './div[@class=\"u-datagrid-page\"]',
                                                           timeout=self.timeout)
            refresh_button = page_div.find_elements_by_attribute('css selector', 'a.refresh_btn',
                                                                 timeout=self.timeout)
            refresh_button.secure_click()
            sleep(0.5)
            next_button = page_div.find_elements_by_attribute('css selector', 'a.next_page_btn',
                                                              timeout=self.timeout)
            if 'disabled' not in next_button.get_attribute('class'):
                logger.debug('翻下一页查找。')
                next_button.secure_click()
                sleep(0.5)
                table_cell = self.__get_table_page_cell(tablediv, table, titlename, (row - rows))
            else:
                raise SeleniumError('行数已超出表格总行数！')
        else:
            titleindex = titlelist.index(titlename)
            logger.debug(str(titleindex) + '列，名称' + titlename)
            table_cell = celllist[int(titleindex + (len(titlelist) * (row - 1)))]
        return table_cell

    def choose_row_in_nesting_table(self, outerinfo, innerinfo, idname:dict=dict(), father=None):
        '''
        jres2.0的嵌套表格的外部表格行勾选

        :Args:
         - outerinfo: 输入数据，外层表格的列名和列名信息
         - innerinfo: 输入数据，内层表格的列名和列名信息，支持列名下多个列名信息匹配，
             以','隔开，如：{'客户编号':'客户111201,客户211201'}
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Raises:
            SeleniumError: 未勾选到表格的数据行


        :Example:
         - 例: select.choose_row_in_nesting_table(outerinfo, innerinfo,, {"xpath",".//*[@class='class']"})
        '''
        try:
            if father is None:
                father = self._driver

            if isinstance(idname, dict) and len(idname) != 0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    if key in key_list:
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
                                                          timeout=self.timeout)
            else:
                tablediv = father.find_element_by_attribute('css selector',
                                                            'div.g-datagrid-wrap.hc_treetable',
                                                            timeout=self.timeout)
            # 翻至表格首页
            page_div = tablediv.find_element_by_attribute('css selector', 'div.u-datagrid-page',
                                                          timeout=self.timeout)
            first_page = page_div.find_element_by_attribute('css selector', 'li>a.first_page_btn',
                                                            timeout=self.timeout)
            if 'disable' not in first_page.get_attribute('class'):
                # first_page.secure_click()
                BaseElement(first_page).click()
                sleep(0.5)
            # 获取数据所在的外层表格行
            outer_row = self.__get_nesting_table_outer_row(tablediv, outerinfo)
            # 进行外层表格行勾选
            outer_table = tablediv.find_element_by_attribute('css selector',
                                                             'div.u-datagrid>table.u-datagrid-group',
                                                             timeout=self.timeout)
            outer_choose_tr = outer_table.find_elements_by_attribute('css selector',
                                                                     'tbody>tr.tree-table-bg',
                                                                     timeout=self.timeout)[int(outer_row - 1)]
            check_td = outer_choose_tr.find_element_by_attribute('css selector', 'td.u-table-check',
                                                                 timeout=self.timeout)
            checkbox = check_td.find_element_by_attribute('css selector', 'input[type="checkbox"]',
                                                          timeout=self.timeout)
            checkbox.secure_click()
            # 展开内层嵌套表格
            open_td = outer_choose_tr.find_element_by_attribute('css selector', 'td.u-table-number',
                                                                timeout=self.timeout)
            span = open_td.find_element_by_attribute('css selector', 'span.fa-stack',
                                                     timeout=self.timeout)
            span.secure_click()
            # 获取数据所在的内层表格行
            inner_table_tr = outer_choose_tr.find_elements_by_attribute('xpath', './following-sibling::tr',
                                                                        timeout=self.timeout)[0]
            inner_table = inner_table_tr.find_element_by_attribute('css selector', 'table.u-datagrid-group',
                                                                   timeout=self.timeout)
            inner_row_list = self.__get_nesting_table_inner_row(inner_table, innerinfo)
            # 进行内层表格行勾选
            for inner_row in inner_row_list:
                inner_choose_td = inner_table.find_element_by_attribute(
                    'css selector', 'tbody>tr:nth-child(' + str(inner_row) + ')>td.u-table-check',
                    timeout=self.timeout)
                inner_choose_td.find_element_by_attribute('tag name', 'input',
                                                          timeout=self.timeout).secure_click()
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))

    def __get_nesting_table_outer_row(self, tablediv, tableinfo):
        keylist = list(tableinfo.keys())
        logger.debug('表格查找列名索引：' + str(keylist))
        # 获取表格列名列表
        table = tablediv.find_element_by_attribute('css selector',
                                                   'div.u-datagrid>table.u-datagrid-group',
                                                   timeout=self.timeout)
        # titlelist = table.get_table_title()
        titlelist = self.get_table_title_list(table)
        logger.debug('表格当前显示列名：' + str(titlelist))
        rowlist_list = list()
        for key in keylist:
            # 表格当前页查找
            titleindex = titlelist.index(key)
            logger.debug('第' + str(titleindex + 1) + '列，名称：' + key)
            # textlist = table.get_table_text(len(titlelist), int(titleindex + 1))
            textlist = self.get_table_text_list(table,(titlelist), int(titleindex + 1))
            rows = len(textlist)
            logger.debug('当前页显示行数：' + str(rows))
            templist = list()
            for j in range(0, rows):
                if textlist[j] == tableinfo[key]:
                    logger.debug('第' + str(j + 1) + '行，内容：' + textlist[j])
                    row = j + 1
                    templist.append(row)
            rowlist_list.append(templist)
        rowlist = rowlist_list[0]
        for i in range(1, len(rowlist_list)):
            rowlist = get_same_value_in_lists(rowlist, rowlist_list[i])
        # 未找到数据行则进行表格翻页
        if len(rowlist) > 0:
            return rowlist[0]
        else:
            # 进行翻页操作
            page_div = tablediv.find_element_by_attribute('css selector', 'div.u-datagrid-page',
                                                          timeout=self.timeout)
            next_button = page_div.find_element_by_attribute('css selector', 'a.next_page_btn',
                                                             timeout=self.timeout)
            if 'disabled' not in next_button.get_attribute('class'):
                logger.debug('翻下一页查找。')
                next_button.secure_click()
                sleep(0.5)
                return self.__get_nesting_table_outer_row(tablediv, tableinfo)
            else:
                logger.error('未找到目标数据行！')

    def __get_nesting_table_inner_row(self, table, tableinfo):
        keylist = list(tableinfo.keys())
        logger.debug('表格查找列名索引：' + str(keylist))
        # 获取表格列名列表
        # titlelist = table.get_table_title()
        titlelist = self.get_table_title_list(table)
        logger.debug('表格当前显示列名：' + str(titlelist))
        rowlist_list = list()
        for key in keylist:
            # 表格当前页查找
            titleindex = titlelist.index(key)
            logger.debug('第' + str(titleindex + 1) + '列，名称：' + key)
            # textlist = table.get_table_text(len(titlelist), int(titleindex + 1))
            textlist = self.get_table_text_list(table, len(titlelist), int(titleindex + 1))
            rows = len(textlist)
            logger.debug('当前页显示行数：' + str(rows))
            templist = list()
            for j in range(0, rows):
                valuelist = tableinfo[key].split(',')
                for value in valuelist:
                    if textlist[j] == value:
                        logger.debug('第' + str(j + 1) + '行，内容：' + textlist[j])
                        row = j + 1
                        templist.append(row)
            rowlist_list.append(templist)
        rowlist = rowlist_list[0]
        for i in range(1, len(rowlist_list)):
            rowlist = get_same_value_in_lists(rowlist, rowlist_list[i])
        # 未找到数据行则进行表格翻页
        if len(rowlist) > 0:
            return rowlist
        else:
            logger.error('未找到目标数据行！')

    def deal_checkbox_in_table(self, value, idname:list=list(), father=None):
        '''
        处理jires2.0复选框表格中勾选

        :Args:
         - value: 要勾选的选项值，以‘,’隔开多选项
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            返回勾选选中的数量

        :Example:
         - 例: select.deal_checkbox_in_table(value, {"xpath",".//*[@class='class']"})
        '''
        try:
            if father is None:
                father = self._driver
            if isinstance(idname, dict) and len(idname) != 0:
                element_by = ''
                element_value = ''
                assist = ''
                for key, value in idname.items():
                    if key in key_list:
                        element_by = key
                        element_value = value
                    else:
                        assist += '{}:{},'.format(key, value)
                assist = assist.strip(',')
                topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
                                                          timeout=self.timeout)
            else:
                table = father.find_element_by_attribute('tag name', 'table,class:m_checkbox_ground',
                                                         timeout=self.timeout)
            # 确保表格中的复选框全不选
            celllist = table.find_elements_by_attribute('xpath', './tbody/*/td', timeout=self.timeout)
            textlist = self.get_table_text_list(table)
            # textlist = table.get_table_text()
            all_input = None
            for i in range(0, len(celllist)):
                if re.search('^\s*全选\s*$', textlist[i]):
                    all_input = celllist[i].find_element_by_attribute('tag name', 'input', 'type:checkbox',
                                                                      timeout=self.timeout)
                    break
            while True:
                all_input.secure_click()
                any_input = celllist[1].find_element_by_attribute('tag name', 'input', 'type:checkbox',
                                                                  timeout=self.timeout)
                if any_input.get_attribute('checked'):
                    continue
                else:
                    break
            # 进行选项选择
            num = 0
            logger.debug('选择选项：' + value)
            if value == '全选':
                # all_input.secure_click()
                BaseElement(all_input).click()
                num += len(textlist) - 1
            else:
                valuelist = value.split(',')
                for va in valuelist:
                    for i in range(0, len(celllist)):
                        if re.search('^\s*'+va+'\s*$', textlist[i]):
                            celllist[i].find_element_by_attribute('tag name', 'input', 'type:checkbox',
                                                                  timeout=self.timeout).secure_click()
                            num += 1
                            break
                    else:
                        logger.warn('未找到选项：' + va)
            return num
        except Exception as msg:
            logger.error(str(msg))
            return 0

    # def do_form_in_edit_table(self, inputData, idname:dict=dict(), father=None):
    #     '''
    #     jres2.0的可编辑表格表单一键抓取
    #
    #     :Args:
    #      - inputData: 列名为key的变淡填充数据，字典类型
    #      - idname: 表格的定位条件
    #      - idname[0]: 元素查找方式
    #      - idname[1]: 元素查找语句
    #      - idname[2]: 查找的辅助属性
    #      - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找
    #
    #     :Returns:
    #         填充成功返回True，否则返回False
    #
    #     :Raises:
    #         SeleniumError: 填充时出错
    #     '''
    #     try:
    #         if father is None:
    #             father = self._driver
    #         if isinstance(idname, dict) and len(idname) != 0:
    #             element_by = ''
    #             element_value = ''
    #             assist = ''
    #             for key, value in idname.items():
    #                 if key in key_list:
    #                     element_by = key
    #                     element_value = value
    #                 else:
    #                     assist += '{}:{},'.format(key, value)
    #             assist = assist.strip(',')
    #             topdiv = father.find_element_by_attribute(element_by, element_value, assist=assist,
    #                                                       timeout=self.timeout)
    #         else:
    #             topdiv = father.find_element_by_attribute(
    #                 'css selector', 'div.xeditgrid.g-datagrid-wrap', timeout=self.timeout)
    #         # 进行新增行
    #         toolbar_ul = topdiv.find_element_by_attribute(
    #             'css selector', 'div.u-datagrid-toolbar>ul.u-datagrid-btn', timeout=self.timeout)
    #         add_btn = toolbar_ul.find_element_by_attribute('link text', '新增', timeout=self.timeout)
    #         # add_btn.secure_click()
    #         BaseElement(add_btn).click()
    #         # 获取表格列名
    #         table = topdiv.find_element_by_attribute(
    #             'css selector', 'div.hs-outer-trusteditgrid>table.hs-factor-trusteditgrid',
    #             timeout=self.timeout)
    #         titlelist = self.__get_table_title_in_td(table)
    #         logger.debug('表格当前显示列名：' + str(titlelist))
    #         # 获取表格新增行元素
    #         new_tr = table.find_elements_by_attribute('css selector', 'tbody>tr', timeout=self.timeout)[-1]
    #         for input_key, input_value in inputData.items():
    #             if input_value == '':
    #                 continue
    #             key, value, flag, label_seq = deal_inputdata(input_key, input_value)
    #             index = titlelist.index(key)
    #             td = new_tr.find_elements_by_attribute('tag name', 'td', timeout=self.timeout)[index]
    #             div = td.find_element_by_attribute('css selector', 'div.content', timeout=self.timeout)
    #             temp_pass = Form(self._driver).confirm_type(div, key, value, flag)
    #             if temp_pass is False:
    #                 return False
    #     except Exception as msg:
    #         logger.error(str(msg))
    #         raise SeleniumError(str(msg))
    #     else:
    #         return True

    def do_form_in_edit_table(self, inputData):
        '''
        jres2.0的可编辑表格表单一键抓取

        :Args:
         - inputData: 列名为key的变淡填充数据，字典类型
         - idname: 表格的定位条件
         - idname[0]: 元素查找方式
         - idname[1]: 元素查找语句
         - idname[2]: 查找的辅助属性
         - father: table的祖先级元素，可以给表格查找限定范围，这样就不需要在整个页面中查找

        :Returns:
            填充成功返回True，否则返回False

        :Raises:
            SeleniumError: 填充时出错

        :Example:
         - 例: select.do_form_in_edit_table({"客户信息":"1234"})
        '''
        try:
            # 进行新增行
            toolbar_ul_locator = "div.u-datagrid-toolbar>ul.u-datagrid-btn"
            toolbar_uls = self._driver.find_elements_by_attribute('css selector', toolbar_ul_locator, timeout=self.timeout)
            toolbar_ul = None
            for temp in toolbar_uls:
                if temp.is_displayed():
                    toolbar_ul = temp
                    break

            add_btn = toolbar_ul.find_element_by_attribute('link text', '新增', timeout=self.timeout)
            # add_btn.secure_click()
            BaseElement(add_btn).click()
            # 获取表格列名
            # table = topdiv.find_element_by_attribute(
            #     'css selector', 'div.hs-outer-trusteditgrid>table.hs-factor-trusteditgrid',
            #     timeout=self.timeout)
            locator = "table.hs-factor-trusteditgrid"
            tables = self._driver.find_elements_by_attribute('css selector', locator, timeout=self.timeout)
            table = None
            for temp in tables:
                if temp.is_displayed():
                    table = temp
                    break
            titlelist = self.__get_table_title_in_td(table)
            logger.debug('表格当前显示列名：' + str(titlelist))
            # 获取表格新增行元素
            new_tr = table.find_elements_by_attribute('css selector', 'tbody>tr', timeout=self.timeout)[-1]
            for input_key, input_value in inputData.items():
                if input_value == '':
                    continue
                key, value, flag, label_seq = deal_inputdata(input_key, input_value)
                index = titlelist.index(key)
                td = new_tr.find_elements_by_attribute('tag name', 'td', timeout=self.timeout)[index]
                div = td.find_element_by_attribute('css selector', 'div.content', timeout=self.timeout)
                datatable = None
                datatables = self._driver.find_elements_by_attribute("css selector",".datatable", timeout=self.timeout)
                for temp in datatables:
                    if temp.is_displayed:
                        datatable = temp
                        break
                temp_pass = Form(datatable).confirm_type(div, key, value, flag)
                if temp_pass is False:
                    return False
        except Exception as msg:
            logger.error(str(msg))
            raise SeleniumError(str(msg))
        else:
            return True